//#define USE_DUNGEONBUDDY_DLL

using System;
using System.Collections.Generic;
using CommonBehaviors.Actions;
using Styx;
using Styx.CommonBot;
using Styx.CommonBot.Frames;
using Styx.Pathing;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using Styx.TreeSharp;
using Action = Styx.TreeSharp.Action;

#if USE_DUNGEONBUDDY_DLL
using Bots.DungeonBuddyDll;
using Bots.DungeonBuddyDll.Attributes;
using Bots.DungeonBuddyDll.Helpers;

namespace Bots.DungeonBuddyDll.Dungeon_Scripts.Burning_Crusade
#else
    using Bots.DungeonBuddy.Attributes;
    using Bots.DungeonBuddy.Helpers;
    namespace Bots.DungeonBuddy.Dungeon_Scripts.Burning_Crusade
#endif

{
    public class HellfireRamparts : Dungeon
    {
        #region Overrides of Dungeon

        /// <summary>
        ///   The mapid of this dungeon.
        /// </summary>
        /// <value> The map identifier. </value>
        public override uint DungeonId
        {
            get { return 136; }
        }

        public override WoWPoint Entrance
        {
            get { return new WoWPoint(-365.0169, 3093.254, -14.35639); }
        }

        public override WoWPoint ExitLocation
        {
            get { return new WoWPoint(-1357.323, 1635.028, 68.53062); }
        }

        public override void WeighTargetsFilter(List<Targeting.TargetPriority> units)
        {
            foreach (var p in units)
            {
                var unit = p.Object as WoWUnit;
                if (unit == null) continue;
                if ((unit.Entry == FiendishHoundId || unit.Entry == HellfireWatcherId) && Me.IsDps())
                {
                    p.Score += 1000;
                }
            }
        }

        #endregion

        private const uint FiendishHoundId = 17540;
        private const uint HellfireWatcherId = 17309;

        private LocalPlayer Me
        {
            get { return StyxWoW.Me; }
        }

        [EncounterHandler(54606, "Stone Guard Stok'ton", Mode = CallBehaviorMode.Proximity, BossRange = 30)]
        public Composite QuestPickupHandler()
        {
            WoWUnit unit = null;
            return new PrioritySelector(
                ctx => unit = ctx as WoWUnit,
                new Decorator(
                    ctx => !Me.Combat && !ScriptHelpers.WillPullAggroAtLocation(unit.Location) && unit.QuestGiverStatus == QuestGiverStatus.Available,
                    ScriptHelpers.CreatePickupQuest(() => unit)),
                new Decorator(
                    ctx => !Me.Combat && !ScriptHelpers.WillPullAggroAtLocation(unit.Location) && unit.QuestGiverStatus == QuestGiverStatus.TurnIn,
                    ScriptHelpers.CreateTurninQuest(() => unit)));
        }

        [EncounterHandler(17536, "Nazan")]
        public Composite NazanEncounter()
        {
            WoWUnit unit = null;
            const uint liquidFireId = 181890;

            AddAvoidObject(ctx => !Me.IsCasting, 3f, liquidFireId);

            return new PrioritySelector(
                ctx => unit = ctx as WoWUnit,
                ScriptHelpers.CreateAvoidUnitAnglesBehavior(ctx => !Me.IsTank() && unit.CurrentTargetGuid != Me.Guid, () => unit, new ScriptHelpers.AngleSpan(0, 180)),
                ScriptHelpers.CreateTankFaceAwayGroupUnit(15));
        }


        [EncounterHandler(17536, "Omor the Unscarred")]
        public Composite OmorTheUnscarredEncounter()
        {
            AddAvoidObject(ctx => !Me.IsTank() && Me.HasAura("Bane of Treachery"), 15, o => o is WoWPlayer && !o.IsMe);
            return new PrioritySelector();
        }

        [ObjectHandler(209347, "Hellfire Supplies", ObjectRange = 30)]
        public Composite HellfireSuppliesHandler()
        {
            WoWGameObject supplies = null;
            PlayerQuest quest = null;
            const uint hittingThemWhereItHurtsQuestId = 29593;

            return new PrioritySelector(
                ctx => supplies = ctx as WoWGameObject,
                new Decorator(
                    ctx =>
                    !Blacklist.Contains(supplies, BlacklistFlags.Loot) && (quest = Me.QuestLog.GetQuestById(hittingThemWhereItHurtsQuestId)) != null && !quest.IsCompleted &&
                    !supplies.InUse && !Me.Combat && !ScriptHelpers.WillPullAggroAtLocation(supplies.Location) && Me.Location.PathDistance(supplies.Location) <= 30,
                    new PrioritySelector(
                        new Decorator(ctx => !supplies.WithinInteractRange, new Action(ctx => Navigator.MoveTo(supplies.Location))),
                        new Decorator(
                            ctx => supplies.WithinInteractRange,
                            new Sequence(
                                new DecoratorContinue(ctx => Me.IsMoving, new Action(ctx => WoWMovement.MoveStop())),
                                new WaitContinue(2, ctx => !Me.IsMoving, new ActionAlwaysSucceed()),
                                new Action(ctx => supplies.Interact()),
                                new WaitContinue(4, ctx => false, new ActionAlwaysSucceed()),
                                new Action(ctx => LootFrame.Instance.LootAll()),
                                new Action(ctx => Blacklist.Add(supplies, BlacklistFlags.Loot, TimeSpan.FromMinutes(5))))))));
        }

        [ObjectHandler(185168, "Reinforced Fel Iron Chest")]
        public Composite ReinforcedFelIronChestHandler()
        {
            WoWGameObject chest = null;
            return new PrioritySelector(
                ctx => chest = ctx as WoWGameObject,
                new Decorator(
                    ctx => !chest.InUse && chest.CanUse() && !Blacklist.Contains(chest,BlacklistFlags.Loot),
                    new PrioritySelector(
                        new Decorator(ctx => !chest.WithinInteractRange, new Action(ctx => Navigator.MoveTo(chest.Location))),
                        new Sequence(
                                new DecoratorContinue(ctx => Me.IsMoving, new Action(ctx => WoWMovement.MoveStop())),
                                new WaitContinue(2, ctx => !Me.IsMoving, new ActionAlwaysSucceed()),
                                new Action(ctx => chest.Interact()),
                                new WaitContinue(3, ctx => false, new ActionAlwaysSucceed()),
                                new Action(ctx => LootFrame.Instance.LootAll()),
                                new Action(ctx => Blacklist.Add(chest, BlacklistFlags.Loot, TimeSpan.FromMinutes(10)))))));
        }

        #region Watchkeeper Gargolmar

        [EncounterHandler(17306, "Watchkeeper Gargolmar")]
        public Composite WatchkeeperGargolmarEncounter()
        {
            WoWUnit boss = null;
            return new PrioritySelector(ctx => boss = ctx as WoWUnit, ScriptHelpers.CreateDispellEnemy("Renew", ScriptHelpers.EnemyDispellType.Magic, () => boss));
        }

        [EncounterHandler(17309, "Hellfire Watcher")]
        public Composite HellfireWatcherEncounter()
        {
            WoWUnit unit = null;
            var healIds = new[] { 12039, 30643 };

            return new PrioritySelector(
                ctx => unit = ctx as WoWUnit,
                ScriptHelpers.CreateDispellEnemy("Renew", ScriptHelpers.EnemyDispellType.Magic, () => unit),
                ScriptHelpers.CreateInterruptCast(() => unit, healIds));
        }

        #endregion
    }
}